package com.yonyou.ucf.mdf.app.isvdxq.yonyisv.controller;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.yonyou.ucf.mdf.app.isvdxq.common.DxqConfig;
import com.yonyou.ucf.mdf.app.isvdxq.other.model.ContentBean;
import com.yonyou.ucf.mdf.app.isvdxq.yonyisv.model.EventContent;
import com.yonyou.ucf.mdf.app.isvdxq.common.ISVEventType;
import com.yonyou.ucf.mdf.app.isvdxq.common.SuiteConfig;
import com.yonyou.ucf.mdf.app.isvdxq.crypto.EncryptionHolder;
import com.yonyou.ucf.mdf.app.isvdxq.crypto.IsvEventCrypto;
import com.yonyou.ucf.mdf.app.isvdxq.other.entity.SuiteauthEntity;
import com.yonyou.ucf.mdf.app.isvdxq.other.model.Suite;
import com.yonyou.ucf.mdf.app.isvdxq.other.model.SuiteAuth;
import com.yonyou.ucf.mdf.app.isvdxq.other.service.BaseService;
import com.yonyou.ucf.mdf.app.isvdxq.other.service.SuiteService;
import com.yonyou.ucf.mdf.app.isvdxq.other.service.SuiteauthService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.List;

/**
 * 处理套件授权相关的回调事件：1. 推送套件票据 suiteTicket, 2. 推送授权的租户 id。
 * 这里的回调地址填写在套件的编辑页面。
 * /isv/open/auth_push_v2 票据推送
 */
@RequestMapping(value = {DxqConfig.pre_apiUrl+"",DxqConfig.pre_pcUrl+""})
@RestController
public class PushAuthController {

    private static final Logger LOGGER = LoggerFactory.getLogger(PushAuthController.class);

    private ObjectMapper mapper = new ObjectMapper();

    @Autowired
    private BaseService baseService;

    @Autowired
    private SuiteConfig suiteConfig;

    //内存加载
    @Autowired
    private SuiteService suiteService;

    //私有表存储
    @Autowired
    private SuiteauthService suiteauthService;

    @PostMapping("/open/auth_push_v1")
    public String authCallbackHandler(@RequestBody EncryptionHolder holder) throws IOException {
        // 构建解密验签处理对象
        IsvEventCrypto crypto = new IsvEventCrypto(suiteConfig.getSuiteSecret(), suiteConfig.getEncodingAESKey(),
                suiteConfig.getSuiteKey());
        // 验签解密后的消息体
        String decryptMessage = crypto.decryptMsg(holder);
        // 反序列化后的消息内容对象
        EventContent content = mapper.readValue(decryptMessage, EventContent.class);

        // 套件票据推送事件
        if (content.getType().equals(ISVEventType.SUITE_TICKET.toString())) {
            LOGGER.info("新的票据推送事件, suitekey: {}, suiteTicket: {}", content.getSuiteKey(), content.getSuiteTicket());
            handleTicketPush(content);
        }

        // 套件租户授权事件
        if (content.getType().equals(ISVEventType.SUITE_AUTH.toString())) {
            LOGGER.info("新的授权事件, suitekey: {}, authTenantId: {},tenantName:{}", content.getSuiteKey(),
                    content.getAuthTenantId(), content.getTenantName());
            LOGGER.info("order id: {}", content.getOrderBean());
            handleAuthPush(content);
            return "success";
        }

        // 处理成功，回复 "success" 告知开放平台，否则开放平台会重试推送，每分钟一次，重试 60 次
        return "success";
    }

    /**
     * 授权回调
     * @param holder
     * @return
     * @throws IOException
     */
    @PostMapping("/open/auth_push_v2")
    public String authCallbackHandlerv2(@RequestBody EncryptionHolder holder) throws IOException {
        try {
            LOGGER.info("[auth_push_v2]" + new Gson().toJson(holder));
            // 构建解密验签处理对象
            IsvEventCrypto crypto = new IsvEventCrypto(DxqConfig.suiteSecret, null, DxqConfig.suiteKey);
            // 验签解密后的消息体
            String decryptMessage = crypto.decryptMsg(holder);
            // 反序列化后的消息内容对象
            EventContent content = mapper.readValue(decryptMessage, EventContent.class);
            LOGGER.info("[auth_push_v2]" + content.getType());

            // 套件票据推送事件
            if (content.getType().equals(ISVEventType.SUITE_TICKET.toString())) {
                String logtxt = String.format("新的票据推送事件, suitekey: {}, suiteTicket: {}", content.getSuiteKey(), content.getSuiteTicket());
                LOGGER.info(logtxt);
                System.out.println(logtxt);

                handleTicketPush(content);
            }

            // 套件租户授权事件
            if (content.getType().equals(ISVEventType.SUITE_AUTH.toString())) {
                String logtxt = String.format("新的授权事件, suitekey: {}, authTenantId: {},tenantName:{}", content.getSuiteKey(),
                        content.getAuthTenantId(), content.getTenantName());
                logtxt += String.format("order id: {}", content.getOrderBean());
                LOGGER.info(logtxt);
                System.out.println(logtxt);

                handleAuthPush(content);
                return "success";
            }
        } catch (Exception ex) {
            String logtxt = String.format("[auth_push_v2]" + ex.getMessage());
            System.out.println(logtxt);
            LOGGER.info(logtxt);
        }
        // 处理成功，回复 "success" 告知开放平台，否则开放平台会重试推送，每分钟一次，重试 60 次
        return "success";
    }


    /**
     * 处理套件票据 (suiteTicket) 推送事件
     * 将票据进行存储，票据 20 分钟推送一次，有效期 20 分钟
     * 开发者需要对推送的票据进行存储，每个套件对应一个有效的票据
     *
     * @param content
     */
    private void handleTicketPush(EventContent content) {
        Suite suite = new Suite();
        suite.setSuiteKey(content.getSuiteKey());
        suite.setSuiteTicket(content.getSuiteTicket());
        suite.setSuiteSecret(content.getSuiteSecret());
        try{
            String userId = "";
            if (content.getUserId()!=null) userId = JSONObject.toJSONString(content.getUserId());
            String context = content.getContent();
            if (StringUtils.isEmpty(userId) && !StringUtils.isEmpty(context)) {
                ContentBean contentBean = JSONObject.parseObject(context, ContentBean.class);
                userId = contentBean.getYhtUser();
            }
            String tenantId = content.getAuthTenantId();
            baseService.AppconfigInit(tenantId, userId);
            baseService.TenantConfigAdd(tenantId, userId, content.getSuiteTicket(), content.getSuiteKey(), content.getSuiteSecret());
        }
        catch (Exception ex){
            LOGGER.info("::[handleTicketPush]" + ex.getMessage());
            System.out.println("[handleTicketPush]" + ex.getMessage());
        }
        // 首次加载数据
        int lenSuiteStore = suiteService.getLenSuiteStore();
        if (lenSuiteStore==0){
            List<SuiteauthEntity> suiteauthEntities = suiteauthService.SelectAll();
            suiteauthEntities.forEach(item->{
                Suite suiteItem = new Suite();
                suiteItem.setSuiteKey(item.getSuiteKey());
                suiteItem.setSuiteTicket(item.getTicket());
                suiteItem.setSuiteSecret(item.getSuiteSecret());
                suiteService.saveSuite(suiteItem);
            });
        }
        suiteService.saveSuite(suite);
    }

    /**
     * 处理套件授权推送事件
     * 套件授权时开放平台会推送授权的租户 id (tenantId) ，
     * 开发者需要使用 tenantId 调用开放平台接口获得该租户的访问令牌 (accessToken)
     *
     * @param content
     */
    private void handleAuthPush(EventContent content) {
        SuiteAuth suiteAuth = new SuiteAuth();
        suiteAuth.setSuiteKey(content.getSuiteKey());
        suiteAuth.setTenantId(content.getAuthTenantId());
        try {
            String userId = "";
            if (content.getUserId()!=null) userId = JSONObject.toJSONString(content.getUserId());
            String context = content.getContent();
            if (StringUtils.isEmpty(userId) && !StringUtils.isEmpty(context)) {
                ContentBean contentBean = JSONObject.parseObject(context, ContentBean.class);
                userId = contentBean.getYhtUser();
            }
            String tenantId = content.getAuthTenantId();
            suiteAuth.setTokenUrl(baseService.buildTokenUrl(tenantId));
            suiteAuth.setGatewayUrl(baseService.buildBusinessUrl(tenantId));
            baseService.AppconfigInit(tenantId, userId);
            baseService.TenantConfigAdd(tenantId, userId, content.getSuiteTicket(), content.getSuiteKey(), content.getSuiteSecret());
        } catch (IOException ex) {
            LOGGER.info("[处理套件授权推送事件]");
            LOGGER.info("::[handleAuthPush]" + ex.getMessage());
            System.out.println("[handleAuthPush]" + ex.getMessage());
        }
        // 首次加载数据
        int lenSuiteAuthStore = suiteService.getLenSuiteAuthStore();
        if (lenSuiteAuthStore==0){
            List<SuiteauthEntity> suiteauthEntities = suiteauthService.SelectAll();
            suiteauthEntities.forEach(item->{
                SuiteAuth suiteAuthItem = new SuiteAuth();
                suiteAuthItem.setSuiteKey(item.getSuiteKey());
                suiteAuthItem.setTenantId(item.getTenant_id());
                suiteService.saveSuiteAuth(suiteAuthItem);
            });
        }
        suiteService.saveSuiteAuth(suiteAuth);
    }
}